﻿namespace SenenFernandez.SmartExtensionMethods
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    /// <summary>
    /// Provides constants and static methods for common mathematical functions.
    /// </summary>
    public static class SmartMath
    {
        /// <summary>
        /// Gets Percent.
        /// </summary>
        public static double Percent(this double value, double percentage)
        {
            return (value * percentage) / 100.0;
        }

        /// <summary>
        /// Increment in Percent.
        /// </summary>
        public static double IncrementPercent(this double value, double percentage)
        {
            return value + Percent(value, percentage);
        }

        /// <summary>
        /// Gets the Standard Deviation.
        /// </summary>
        public static double StandardDeviation(this List<double> values)
        {
            double avg = values.Average();
            return Math.Sqrt(values.Average(value => Math.Pow(value - avg, 2)));
        }

        /// <summary>
        /// Gets Fibonacci List.
        /// In honor of my teacher and friend Carlos A. Rojas Kramer =)
        /// </summary>
        public static IEnumerable<double> GetFibonacciList(this int max)
        {
            double previous = 0;
            double current = 1;
            var list = new List<double>();
            do
            {
                list.Add(previous);
                list.Add(current);
                previous += current;
                current += previous;
            } while (list.Count < max);
            return list;
        }

        /// <summary>
        /// Gets Prime Numbers List.
        /// </summary>
        public static IEnumerable<int> GetPrimeNumbers(this int max)
        {
            var list = new List<int>();
            int prime = 2;
            for (int count = 0; count < max; prime++)
            {
                bool isPrime = true;
                for (int mod = 2; mod <= Math.Sqrt(prime); mod++)
                {
                    if (prime % mod == 0)
                    {
                        isPrime = false;
                        break;
                    }
                }
                if (isPrime)
                {
                    list.Add(prime);
                    count++;
                    if (count == max)
                    {
                        break;
                    }
                }
            }
            return list;
        }
    }
}